package com.controller.sys.user;

import com.common.ErrorCodeEnum;
import com.model.base.Result;
import com.common.anntation.Log;
import com.common.emums.BusinessType;
import com.model.dto.sys.userController.*;
import com.common.exception.BusinessException;
import com.common.utils.ServletUtils;
import com.core.email.EmailService;
import com.core.sms.service.SmsServer;
import com.core.springSecurity.model.LoginUserDetails;
import com.core.springSecurity.service.TempUserKeyService;
import com.core.springSecurity.service.TokenService;
import com.model.pojo.sys.SysUser;
import com.model.vo.user.PasswordKeyVO;
import com.service.sys.SysUserService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.validation.Valid;
import java.util.Objects;

/**
 * @Author: zql
 * @Description: 密码管理服务，忘记密码身份验证规则
 * @Data: 17:15 2021/7/21
 */
@Api(tags = {"个人安全中心"})
@Slf4j
@RestController
@RequestMapping("/v1")
public class PasswordController {

    @Resource
    SysUserService sysUserService;

    @Resource
    EmailService emailService;

    @Resource
    SmsServer smsServer;

    @Resource
    TempUserKeyService tempUserKeyService;

    @Resource
    TokenService tokenService;

    /**
     * @Author: zql
     * @Description: 校验邮箱验证码，如果校验通过生成一个临时的密钥并返回
     * @param getPasswordKeyByEmailDTO 邮箱+验证码
     * @Data: 9:41 2021/7/23
     */
    @ApiOperation(value = "通过验证邮箱验证码获取临时密钥")
    @Log(title = "通过验证邮箱验证码获取临时密钥", businessType = BusinessType.GRANT)
    @PostMapping("/getPasswordKeyByEmail")
    public Result<PasswordKeyVO> getPasswordKeyByEmail(@RequestBody @Valid GetPasswordKeyByEmailDTO getPasswordKeyByEmailDTO) {
        if (!sysUserService.hasEmail(getPasswordKeyByEmailDTO.getEmail())) {
            throw new BusinessException(ErrorCodeEnum.USER_DATA_NOT_FOUND);
        }
        if (emailService.check(getPasswordKeyByEmailDTO.getEmail(), getPasswordKeyByEmailDTO.getCode())) {
            SysUser sysUser= sysUserService.getByEmail(getPasswordKeyByEmailDTO.getEmail());
            String passwordKey = tempUserKeyService.createPasswordKey(sysUser.getSysUserId());
            //生成key保存到redis并返回
            PasswordKeyVO passwordKeyVO=new PasswordKeyVO();
            passwordKeyVO.setPasswordKey(passwordKey);
            return Result.suc(passwordKeyVO);
        }
        return Result.fail(ErrorCodeEnum.EMAIL_CODE_VERIFY_FAILED);
    }


    /**
     * @Author: zql
     * @Description: 校验手机短信验证码，如果校验通过生成一个临时的密钥并返回
     * @param getPasswordKeyByMobileDTO 手机号+验证码
     * @Data: 9:42 2021/7/23
     */
    @ApiOperation(value = "通过验证手机验证码获取临时密钥")
    @Log(title = "通过验证手机验证码获取临时密钥", businessType = BusinessType.GRANT)
    @PostMapping("/getPasswordKeyByMobile")
    public Result<PasswordKeyVO> getPasswordKeyByMobile(@RequestBody @Valid GetPasswordKeyByMobileDTO getPasswordKeyByMobileDTO) {
        if (!sysUserService.hasMobile(getPasswordKeyByMobileDTO.getMobile())) {
            throw new BusinessException(ErrorCodeEnum.USER_DATA_NOT_FOUND);
        }
        if (smsServer.check(getPasswordKeyByMobileDTO.getMobile(), getPasswordKeyByMobileDTO.getCode())) {
            SysUser sysUser= sysUserService.getByMobile(getPasswordKeyByMobileDTO.getMobile());
            String passwordKey = tempUserKeyService.createPasswordKey(sysUser.getSysUserId());
            //生成key保存到redis并返回
            PasswordKeyVO passwordKeyVO=new PasswordKeyVO();
            passwordKeyVO.setPasswordKey(passwordKey);
            return Result.suc(passwordKeyVO);
        }
        return Result.fail(ErrorCodeEnum.MOBILE_CODE_VERIFY_FAILED);
    }

    /**
     * @Author: zql
     * @Description: 通过临时密钥进行重置密码
     * @param resetPasswordDTO 临时密钥+新密码
     * @Data: 9:42 2021/7/23
     */
    @ApiOperation(value = "重置密码")
    @Log(title = "重置密码", businessType = BusinessType.UPDATE)
    @PostMapping("/resetPassword")
    public Result<Objects> resetPassword(@RequestBody @Valid ResetPasswordDTO resetPasswordDTO) {
        Long sysUserId = tempUserKeyService.getValueByPasswordKey(resetPasswordDTO.getPasswordKey());
        if (!sysUserService.has(sysUserId)) {
            throw new BusinessException(ErrorCodeEnum.USER_DATA_NOT_FOUND);
        }
        sysUserService.resetPassword(sysUserId,resetPasswordDTO.getNewPassword());
        return Result.suc();
    }

    @ApiOperation(value = "更新个人手机")
    @Log(title = "更新个人手机", businessType = BusinessType.UPDATE,  isSaveRequestData = true, isSaveResponseData = true)
    @PostMapping("/updatePhone")
    public Result<Objects> updatePhone(@RequestBody @Valid UpdatePhoneDTO updatePhoneDTO) {
        if (!smsServer.check(updatePhoneDTO.getNewMobile(), updatePhoneDTO.getMobileCode())) {
            throw new BusinessException(ErrorCodeEnum.MOBILE_CODE_VERIFY_FAILED);
        }
        Long sysUserId = tempUserKeyService.getValueByPasswordKey(updatePhoneDTO.getPasswordKey());
        if (!sysUserService.has(sysUserId)) {
            throw new BusinessException(ErrorCodeEnum.USER_DATA_NOT_FOUND);
        }
        if(sysUserService.hasMobile(updatePhoneDTO.getNewMobile())){
            throw new BusinessException(ErrorCodeEnum.USER_EMAIL_EXISTS);
        }
        sysUserService.resetMobile(sysUserId,updatePhoneDTO.getNewMobile());
        //更新缓存的手机号
        LoginUserDetails loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
        loginUser.getUser().setMobile(updatePhoneDTO.getNewMobile());
        tokenService.setLoginUser(loginUser);
        return Result.suc();
    }

    @ApiOperation(value = "更新个人邮箱")
    @Log(title = "更新个人邮箱", businessType = BusinessType.UPDATE,  isSaveRequestData = true, isSaveResponseData = true)
    @PostMapping("/updateEmail")
    public Result<Objects> updateEmail(@RequestBody @Valid UpdateEmailDTO updateEmailDTO) {
        if (!emailService.check(updateEmailDTO.getNewEmail(), updateEmailDTO.getEmailCode())) {
            throw new BusinessException(ErrorCodeEnum.EMAIL_CODE_VERIFY_FAILED);
        }
        Long sysUserId = tempUserKeyService.getValueByPasswordKey(updateEmailDTO.getPasswordKey());
        if (!sysUserService.has(sysUserId)) {
            throw new BusinessException(ErrorCodeEnum.USER_DATA_NOT_FOUND);
        }
        if(sysUserService.hasEmail(updateEmailDTO.getNewEmail())){
            throw new BusinessException(ErrorCodeEnum.USER_EMAIL_EXISTS);
        }
        sysUserService.resetEmail(sysUserId,updateEmailDTO.getNewEmail());
        //更新缓存的Email
        LoginUserDetails loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
        loginUser.getUser().setEmail(updateEmailDTO.getNewEmail());
        tokenService.setLoginUser(loginUser);
        return Result.suc();
    }
}
